/*
 * acooly.cn Inc.
 * Copyright (c) 2016 All Rights Reserved.
 * create by zhangpu 
 * date:2016年5月1日
 *
 */
package com.acooly.openapi.client.provider.bosc;

import com.acooly.core.utils.Strings;
import com.acooly.core.utils.mapper.CsvMapper;
import com.acooly.module.openapi.client.api.enums.ApiMessageType;
import com.acooly.module.openapi.client.api.message.ApiMessage;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.util.List;

/**
 * 简单API报文生成器
 *
 * @author zhangpu
 */
public class BoscApiMessageBuilder {
	
	// 报文CSV文件目录
	static String messagesPath = "/Users/liunim/coding/openapi-client/openapi-client-test/src/test/resources/message/";
	// 目标工程workspace（到java文件夹的目录）
	static String workspace
			= "/Users/liunim/coding/openapi-client/openapi-client-provider/openapi-client-provider-bosc/src/main/java/";
	
	static String classPath = "com.acooly.module.openapi.client.provider.bosc.message.fund";
	
	static String FILE_NAME = "QUERY_TRANSACTION_UNFREEZE_RESPONSE.csv";
	
	
	public static void main (String[] args) throws Exception {
		
		String serviceName = FILE_NAME.substring (0,FILE_NAME.lastIndexOf ("_"));
		
		
		ApiMessageType messageType = ApiMessageType.Request;
		if(FILE_NAME.contains ("NOTIFY")){
			messageType = ApiMessageType.Notify;
			
		}else if(FILE_NAME.contains ("REQUEST")){
			messageType = ApiMessageType.Request;
			
		}else if(FILE_NAME.contains ("RESPONSE")){
			messageType = ApiMessageType.Response;
		}
		else if(FILE_NAME.contains ("RETURN")){
			messageType = ApiMessageType.Return;
		}
		else{
			throw new RuntimeException ("文件名不规范");
		}
		
		
		genApiMessage (FILE_NAME, serviceName,messageType);
	}
	
	public static void genApiMessage (String fileName, String serviceName, ApiMessageType apiMessageType)
			throws Exception {
		String className = getCanonicalClassName (serviceName, apiMessageType);
		List<String> lines = readLines (messagesPath + fileName);
		StringBuilder sb = new StringBuilder ();
		sb.append ("package ").append (classPath).append (";\r\n")
				.append ("\nimport com.acooly.module.openapi.client.provider.bosc.domain.ApiMsgInfo;")
				.append ("\nimport com.acooly.module.openapi.client.api.enums.ApiMessageType;")
				.append ("\nimport com.acooly.module.openapi.client.provider.bosc.enums.BoscServiceNameEnum;")
				.append ("\nimport com.acooly.module.openapi.client.provider.bosc.domain.BoscRequest;")
				.append ("\nimport org.hibernate.validator.constraints.NotEmpty;")
				.append ("\nimport javax.validation.constraints.Size;")
				.append ("\n\n")
				.append ("@ApiMsgInfo(service = BoscServiceNameEnum.").append (serviceName).append (" ,type = ApiMessageType." +apiMessageType.name () )
				.append (")\n")
				.append ("public class ").append (className).append (" extends Bosc").append (apiMessageType.code ())
				.append (" {\n");
		for (String line : lines) {
			sb.append (generateItemDeclare (line));
		}
		sb.append ("}");
		String targetPath = workspace + Strings.replace (classPath, ".", "/");
		System.out.println (targetPath);
		FileUtils.write (new File (targetPath, className + ".java"), sb.toString (), "UTF-8");
	}
	
	private static List<String> readLines (String filePath) throws Exception {
		return FileUtils.readLines (new File (filePath));
	}
	
	private static String generateItemDeclare (String line) {
		String[] items = CsvMapper.unmarshal (line).toArray (new String[]{});
		String itemName = Strings.trimToEmpty (items[0]);
		String title = Strings.trimToEmpty (items[4]);
		String dataType = Strings.trimToEmpty (items[2]);
		String length = Strings.trimToEmpty (items[3]);
		String required = Strings.trimToEmpty (items[1]);
		
		StringBuilder sb = new StringBuilder ();
		// 备注
		sb.append ("/**\n ").append ("* ").append (title);
		sb.append ("\n */\n");
		
		// 必选
		if (required.equals ("Y")) {
			if (Strings.contains (dataType, "A")) {
			
			} else if (Strings.contains (dataType, "I")) {
			
			} else if (Strings.contains (dataType, "E")) {
				
				sb.append ("@NotNull").append ("\n");
			} else if(Strings.contains (dataType,"T")){
				sb.append ("@NotNull").append ("\n");
			} else {
				sb.append ("@NotEmpty").append ("\n");
			}
		}
		
		if (Strings.contains (dataType, "S")) {
			sb.append ("@Size(max=").append (length).append (")\n");
		} else if (Strings.contains (dataType, "A")) {
			sb.append ("@MoneyConstraint\n");
		} else if (Strings.contains (dataType, "I")) {
			sb.append ("@Max(").append (length).append (")\n");
		} else if (Strings.contains (dataType, "D") || Strings.contains (dataType, "T")) {
			// 暂时不添加
		} else if (Strings.contains (dataType, "E")) {
			// 暂时不添加
		}
		
		sb.append ("private ").append (getJavaType (dataType, itemName)).append (" ")
				.append (getCanonicalFieldName (itemName))
				.append (";\n");
		return sb.toString ();
	}
	
	private static String getJavaType (String dataType, String itemName) {
		
		if (Strings.contains (dataType, "A")) {
			return "Money";
		} else if (Strings.contains (dataType, "I")) {
			return "int";
		} else if (Strings.contains (dataType, "E")) {
			return "Bosc" + Strings.capitalize (itemName) + "Enum";
		} else if(Strings.contains (dataType,"T")){
			return "Date";
		} else {
			return "String";
		}
	}
	
	private static String getSize (String dateType) {
		return Strings.substringBefore (Strings.substringAfter (dateType, "("), ")");
	}
	
	private static String getCanonicalFieldName (String itemName) {
		if (Strings.contains (itemName, "_")) {
			String[] is = Strings.split (itemName, "_");
			StringBuilder sb = new StringBuilder ();
			for (int i = 0; i < is.length; i++) {
				if (i == 0) {
					sb.append (is[i]);
				} else {
					sb.append (Strings.capitalize (is[i]));
				}
			}
			return sb.toString ();
		} else {
			return itemName;
		}
	}
	
	private static String getCanonicalClassName (String serviceName, ApiMessageType apiMessageType) {
		String temp = Strings.lowerCase (serviceName);
		temp = getCanonicalFieldName (temp);
		temp = Strings.capitalize (temp) + apiMessageType.code ();
		return temp;
	}
	
}
